package com.learn.controller;

import com.learn.controller.dto.AddNoticeReq;
import com.learn.controller.dto.NoticeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

@RestController
@RequestMapping("/static")
public class StaticConsumerController {
    // 不存在服务注册与发现机制时，服务的URL只能写死
    private final String DEPT_URL_8001 = "http://localhost:8001/dept";
    private final String DEPT_URL_8002 = "http://localhost:8002/dept";
    private final String NOTICE_URL_9001 = "http://localhost:9001/notice";
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * JDK原生的URLConnection
     */
    @PostMapping("/URLConnection/addDept")
    public String addDept(String name) throws IOException {
        // 请求
        URL url = new URL(DEPT_URL_8001 + "/addDept");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setDoOutput(true);
        
        String param = "name=" + name;
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = param.getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        
        // 响应
        int responseCode = connection.getResponseCode();
        StringBuilder response = new StringBuilder();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
            }
        } else {
            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) {
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
            }
        }
        
        return response.toString();
    }
    
    /**
     * Spring封装的RestTemplate，需要手动@Bean new RestTemplate()
     */
    @PostMapping("/restTemplate/findOneDept")
    public String findOneDept(Integer id) {
        MultiValueMap<String, Integer> params = new LinkedMultiValueMap<>();
        params.add("id", id);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        HttpEntity<MultiValueMap<String, Integer>> request = new HttpEntity<>(params, headers);
        
        return restTemplate.postForObject(DEPT_URL_8001 + "/findOneDept", request, String.class);
    }
    
    @PostMapping("/restTemplate/findAllDept")
    public String findAllDept() {
        return restTemplate.postForObject(DEPT_URL_8001 + "/findAllDept", null, String.class);
    }
    
    @PostMapping("/restTemplate/addNotice")
    public String addNotice(@RequestBody AddNoticeReq req) {
        return restTemplate.postForObject(NOTICE_URL_9001 + "/addNotice", req, String.class);
    }
    
    @PostMapping("/restTemplate/listNoticeByType")
    public String listNoticeByType(NoticeType noticeType) {
        MultiValueMap<String, NoticeType> params = new LinkedMultiValueMap<>();
        params.add("noticeType", noticeType);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        HttpEntity<MultiValueMap<String, NoticeType>> request = new HttpEntity<>(params, headers);
        
        return restTemplate.postForObject(NOTICE_URL_9001 + "/listNoticeByType", request, String.class);
    }
    
    @PostMapping("/restTemplate/findAllNotice")
    public String findAllNotice() {
        return restTemplate.postForObject(NOTICE_URL_9001 + "/findAllNotice", null, String.class);
    }
    
    /**
     * 最常用的Feign会在后续学到服务间通信由Feign客户端完成的时候再讲解
     */
}
